package service

import (
	"crypto/ecdsa"
	"encoding/hex"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/common/hexutil"
	"github.com/ethereum/go-ethereum/core/types"
	"github.com/ethereum/go-ethereum/crypto"
	"github.com/ethereum/go-ethereum/rlp"
	"math/big"
)

const (
	GAS_LIMIT = 21000
	GAS_PRICE = 500000000000
)

func StringToPrivateKey(privateKeyStr string) (*ecdsa.PrivateKey, error) {
	privateKeyByte, err := hexutil.Decode(privateKeyStr)
	if err != nil {
		return nil, err
	}
	privateKey, err := crypto.ToECDSA(privateKeyByte)
	if err != nil {
		return nil, err
	}
	return privateKey, nil
}

func SignTransaction(chainID int64, tx *types.Transaction, privateKeyStr string) (string, error) {
	privateKey, err := StringToPrivateKey(privateKeyStr)
	if err != nil {
		return "", err
	}
	signTx, err := types.SignTx(tx, types.NewEIP155Signer(big.NewInt(chainID)), privateKey)
	if err != nil {
		return "", nil
	}

	b, err := rlp.EncodeToBytes(signTx)
	if err != nil {
		return "", err
	}
	return hex.EncodeToString(b), nil
}

func OfflineTransferETH(chainID int64, nonce uint64, toAddress string, value *big.Int, privk string) (string, error) {
	tx := types.NewTransaction(nonce, common.HexToAddress(toAddress), value, GAS_LIMIT, big.NewInt(GAS_PRICE), nil)
	//types.NewTransactionsByPriceAndNonce()
	return SignTransaction(chainID, tx, privk)
}

//由于types.NewTransaction过时了，官方要求用NewTx方法代替，参考以下代码生成Transaction对象。
var testAddr = common.HexToAddress("b94f5374fce5edbc8e2a8697c15331677e6ebf0b")

var emptyEip2718Tx = types.NewTx(&types.AccessListTx{
	ChainID:  big.NewInt(1),
	Nonce:    3,
	To:       &testAddr,
	Value:    big.NewInt(10),
	Gas:      25000,
	GasPrice: big.NewInt(1),
	Data:     common.FromHex("5544"),
})

var signedEip2718Tx, _ = emptyEip2718Tx.WithSignature(
	types.NewEIP2930Signer(big.NewInt(1)),
	common.Hex2Bytes("c9519f4f2b30335884581971573fadf60c6204f59a911df35ee8a540456b266032f1e8e2c5dd761f9e4f88f41c8310aeaba26a8bfcdacfedfa12ec3862d3752101"),
)
